Repository navigation
fix(lint): connector, permission-set and form-view advisories carry a user sentence in every platform locale - #33145
Conversation
… user sentence in every platform locale Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9qibwqZc5F1URP3eghRix
…-ci8fau # Conflicts: # packages/lint/src/finding-user-text.ts
📓 Docs Drift CheckThis PR changes 1 package(s): 2 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
What this run could not see
Coarse fallback — 4 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin ef3024e52f368c6ab0eb15c77e16887a5ee0a320 && git checkout ef3024e52f368c6ab0eb15c77e16887a5ee0a320
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 6e4a2031f5b16d1849f8af51301b3d6458eb83e2 b5684363d87bd944f619383ffff7157a56e11a58 && git checkout -B drift-repro 6e4a2031f5b16d1849f8af51301b3d6458eb83e2 && git merge --no-ff b5684363d87bd944f619383ffff7157a56e11a58
node scripts/docs-audit/affected-docs.mjs --json 6e4a2031f5b16d1849f8af51301b3d6458eb83e2
|
…-ci8fau # Conflicts: # packages/lint/src/finding-user-text.ts
|
domain:spec#2 · os-tesla · session_01L9qibvfX5bawZKtfa6u7j9 维护者速读
席位意见:可以落地。 席位核对ACCEPT · seat
|
Requested by Tesla · project thread
Fixes #32842
Clause-②: no
Metadata-protocol: none
维护者速读
userTextParams字段,不改变哪些写入被拒、哪些通过;回滚即撤销本 PR。os validate --json/os build --json的 warnings 里这三类提示会多出userTextParams键。lint-connector-credential-literals.user-text.ts(4 种情形,最贴近用户),再看validate-predicate-path-refs.user-text.ts(两种理解都给出写法),最后看authoring-rules.ts里两行转发。pnpm --filter @objectstack/lint exec vitest run src/finding-user-text.connector-permission-form.test.ts,21 个用例全绿,每条都从真实元数据经运行时保存门取出并逐语言渲染。What changes
Three advisory rule ids that the save door returns now carry
userTextParamsand a user sentence in all elevenPLATFORM_LOCALE_TAGS. Each rule file gets a*.user-text.tscatalog beside it, and the three catalogs merge intoFINDING_USER_TEXT_CATALOGthroughmergeUserTextCatalogs, the way #32655 landedvalidate-security-posture.user-text.ts.lint-connector-credential-literals.tsCONNECTOR_CREDENTIAL_LITERALS_USER_TEXTconnector-credential-literalvalidate-retired-permission-residue.tsRETIRED_PERMISSION_RESIDUE_USER_TEXTpermission-retired-lifecycle-residuevalidate-predicate-path-refs.tsPREDICATE_PATH_REFS_USER_TEXTpredicate-rhs-path-shaped(bare-wordwarningarm only)connector-credential-literalhas three push sites and four arms, chosen byposition:headerandenv(a literal in one of the four maps; paramsconnector,name),credential-env(a credential typed intotransport.credentialEnv) andstdio-auth(a stdio MCP server whoseauthreaches nothing); both carry onlyconnector. ⛔ No param and no sentence carries the credential value, following thelint-flow-credential-literalsprecedent. The sentences name the console's own page, Connector credentials (connectorCredentials.title).permission-retired-lifecycle-residue: paramspermissionSet,object,key. The sentence says the line grants nothing, to delete it, and that restore and purge are granted through the recycle bin (recycleBin.title).predicate-rhs-path-shaped: paramsview,word,op, set on the bare-word arm only; the dotted arm refuses the write and carries none. The view name is threaded throughcheckPredicate/walkFields(same file). Per the rule's own note (validate-predicate-path-refs.ts, §One position, one prescription: which reading the author meant is not decided), the sentence names both readings and the supported spelling of each (== 'active', or the field on the left:data.active == 'yes') and never prescribes the root in place (== data.activeis the refused arm).authoring-rules.ts: thelintConnectorCredentialLiteralsandvalidateRetiredPermissionResidueadapters rebuilt findings field by field and droppeduserTextParams; each gets the one-line conditional spread (fix(lint): the approval and flow advisories a flow save returns carry a user sentence in every platform locale #33120, feat(lint): data-model advisories carry a localized user sentence #33140 precedent).validatePredicatePathRefspasses findings through unchanged.32842-advisory-user-text.md,@objectstack/lintpatch.Tests
New
finding-user-text.connector-permission-form.test.ts, 21 tests, in the shape offinding-user-text.data-model.test.ts:FINDING_USER_TEXT_CATALOG; the seven never-at-door ids have no entry;allowRestoreandallowPurge; the bare-word predicate), with noundefined, no unfilled${, every shown name present, and no locale falling back to the English sentence; the four connector arms render apart in every locale;==and!=, and never the root in place; the dotted arm carries no params;runRuntimeAuthoringRules, with the advisory's params checked anduserMessageparsed underRuntimeAuthoringIssueSchema(de-DE, ja-JP, fr-FR).Acceptance notes
Re-measure. The card's table lists 10 ids in 8 files; the static scan matches (each id produces exactly one
warningwhole-stack). Through the save door (runRuntimeAuthoringRuleson each id's own write type with an objects context, maina83c3667), 3 reach a user. This PR writes catalogs and pins for those 3 only. Under #32835's Done-when alternative, the 7 that never reach the door:flowdefault. An agent, app, skill or mapping write dispatches none of them, and a flow write's snapshot carries no agents, apps, skills or mappings. Measured: 0 at the door for each.agent-authoring-withdrawn,default-agent-outside-roster,default-agent-legacy-alias(validate-ai-agent-authoring.ts)mapping-connector-source-unknown(validate-mapping-connector-source.ts)ai-skill-tool-unresolved(validate-ai-tool-references.ts): kept off the door on purpose by ruling 5791822697 (ADR-0109 Decision §3), since a per-write snapshot cannot resolve a skill's tools truthfully.security-external-owner-unmapped(validateExternalOwnerSharing,RUNTIME_OBJECT_ADVISORY_VOLUME)sharing-rule-object-not-shareable(validateSharingRuleEnforceability, pending asharing_ruledoor that carriessharingRules)Agent-written sentences for the native-review round. Every non-English sentence in this PR is agent-written: 3 ids (6 sentences counting the connector's four arms) × 10 locales (zh-Hans, zh-Hant, es, ar, fr, pt-BR, ru, de, ja, ko), in the three
*.user-text.tsfiles above. Terms followui/packages/i18n: Connector credentials 连接器凭据 / 聯結器憑據 / Credenciales de conectores / بيانات اعتماد الموصلات / Identifiants des connecteurs / Credenciais de conectores / Учётные данные коннекторов / Connector-Zugangsdaten / コネクタ認証情報 / 커넥터 자격 증명; recycle bin 回收站 / 回收站 / papelera / سلة المحذوفات / corbeille / lixeira / корзина / Papierkorb / ごみ箱 / 휴지통; permission set as invalidate-security-posture.user-text.ts. zh-Hant uses the console's 聯結器 and 回收站, which differ from the flow catalog's 連接器; the native round may want to settle one spelling. The connectorstdio-authand the predicate sentences carry the most technical wording and are the best first read.Metadata-protocol.
none. The #32655 precedent (#32790) declaredadded/Clause-②: yesbecause it added a spec field (userMessage, theapiauthorable shard); this PR adds no spec field and moves no shard, so it follows #32835's reading for its lint-only sub-cards (#32836, #32837, #32838 allnone).Ruling grep (
ruling|Ruling-ref|maintainer|⛔across the surface, read before editing): connector credential literals 2 (never the value; stdio needscredentialEnv), retired permission residue 3 (director ruling D, not re-adjudicable; table not derived live), predicate path refs 2 (the consumer's ruling on the right side; which reading the author meant is undecided),finding-user-text.ts2, the four never-at-door files 0–2 each (untouched). The sentences keep every one of them; none is reversed.Serial. #32838 (PR #33140) landed on
finding-user-text.tsandauthoring-rules.tswhile this was in flight; main was merged once and every catalog line and adapter spread from both is kept. #33072'svalidate-expressions.tsand expression entry are untouched.Ablations (source, committed first,
scripts/ablation-replace.mjs, anchor 1 → 0 on disk, each restored to the HEAD blob9968f378and verified by hash):lintConnectorCredentialLiteralsadapter spread: 1 failed / 20 passed, exactly the connector-write gate case;validateRetiredPermissionResidueadapter spread: 1 failed / 20 passed, exactly the permission-write gate case.Verification
Head
ad51300d,c371f044merged withorigin/mainat6482c083(once, after #33140 landed onfinding-user-text.ts; conflict on the catalog list resolved by keeping both sides;authoring-rules.tsauto-merged with all four adapter spreads present). After the merge:pnpm install --frozen-lockfile, fullpnpm turbo run build --concurrency=2(lock VERDICT exit 0),packages/runtime/.objectstackcleared.pnpm --filter @objectstack/lint test: 206 files, 8762 tests passed (VERDICT exit 0). Before the merge, atc371f044: 204 files, 8732 passed, 5 skipped.pnpm --filter @objectstack/lint typecheck: exit 0 (includescheck:test-typecheck, debt held).node scripts/check-cli-command-ids.mjs: exit 0.check:nul-bytes: exit 0.@objectstack/metadata-protocol(the save door;protocol.runtime-authoring-gate.test.tsnames these ids): 337 files passed, 7 skipped; 22799 tests passed, 36 skipped.@objectstack/clitest/connector-credential-literal-doors.e2e.test.ts(nightly tier, integration project, spawns the CLI): 2 tests passed.dispatch-gates.mjs --commands --repo objectstack-ai/objectstackatad51300dderives 62 families (identical list toc371f044); every line run with stdin closed, exit captured before any pipe, all 62 exit 0.--ranreconciliation: 62 derived, 62 run, 0 NOT-MEASURED (a derived zero). Record:spec-seat-2/r2026-11-13/out/32842-gates-ran-ad51300d.list.Gate readings that were not exit 0 on the first sweep (c371f04)
check-plugin-teardown-shape --self-testexit 3: the shallow clone could not reach the pinned fixture commit621a4876; after fetching it, exit 0 (and exit 0 in the post-merge sweep).!andClause-②:carries no(narrowing)arm.Generated by Claude Code